// gen_sm2_cert.c
// 编译: gcc gen_sm2_cert.c -o gen_sm2_cert `pkg-config --cflags --libs hitls`
#include <stdio.h>
#include <stdlib.h>
#include <hitls/ssl.h>
#include <hitls/x509.h>
#include <hitls/evp.h>
#include <hitls/pem.h>

int main(void) {
    int ret = -1;
    EVP_PKEY *pkey = NULL;
    X509 *x509 = NULL;
    FILE *f = NULL;

    // 初始化库
    HITLS_Init();

    // 1. 生成 SM2 密钥对
    pkey = EVP_PKEY_new();
    if (!pkey) goto end;
    if (!EVP_PKEY_keygen_SM2(pkey)) {
        fprintf(stderr, "生成 SM2 密钥失败\n");
        goto end;
    }

    // 2. 创建 X509 证书
    x509 = X509_new();
    if (!x509) goto end;
    ASN1_INTEGER_set(X509_get_serialNumber(x509), 1);
    X509_gmtime_adj(X509_get_notBefore(x509), 0);
    X509_gmtime_adj(X509_get_notAfter(x509), 31536000L); // 一年有效

    X509_set_pubkey(x509, pkey);

    X509_NAME *name = X509_NAME_new();
    X509_NAME_add_entry_by_txt(name, "C", MBSTRING_ASC, (unsigned char*)"CN", -1, -1, 0);
    X509_NAME_add_entry_by_txt(name, "O", MBSTRING_ASC, (unsigned char*)"OpenHITLS", -1, -1, 0);
    X509_NAME_add_entry_by_txt(name, "CN", MBSTRING_ASC, (unsigned char*)"sm2test.cn", -1, -1, 0);
    X509_set_subject_name(x509, name);
    X509_set_issuer_name(x509, name);

    // 3. 使用 SM3 签名
    if (!X509_sign(x509, pkey, EVP_sm3())) {
        fprintf(stderr, "签名失败\n");
        goto end;
    }

    // 4. 写入 PEM 文件
    f = fopen("sm2_key.pem", "wb");
    if (!f) goto end;
    PEM_write_PrivateKey(f, pkey, NULL, NULL, 0, NULL, NULL);
    fclose(f); f = NULL;

    f = fopen("sm2_cert.pem", "wb");
    if (!f) goto end;
    PEM_write_X509(f, x509);
    fclose(f); f = NULL;

    printf("已生成 sm2_key.pem 与 sm2_cert.pem\n");
    ret = 0;

end:
    if (f) fclose(f);
    X509_free(x509);
    EVP_PKEY_free(pkey);
    HITLS_Cleanup();
    return ret;
}
